import {designPage, useRefs} from "plain-design-composition";
import {PlButton, Plc, PlcDate, PlcExpand, PlcImage, PlcInput, PlcOv, PlcTextarea, PlIcon, PlRate, PlTablePro, useMessage, useTableOption} from "plain-design";
import React from "react";
// @ts-ignore
import content from './test.md'
import {Markdown} from "@/components/markdown/markdown";
import {PlcMonacoEditor, useMonacoEditor} from "./PlcMonacoEditor";
import {useHttp} from "@/plain-init/useHttp";
import {TableRenderScope} from "plain-design/src/packages/PlTable/plc/utils/plc.type";
import {useSolution} from "./SolutionEditor";
import './exercise.scss'

export default designPage(() => {

    const $message = useMessage()

    const diffToNum = {
        '1_low': {val: 1, status: 'info'},
        '2_medium': {val: 3, status: 'success'},
        '3_high': {val: 4, status: 'warn'},
        '4_superior': {val: 5, status: 'error'},
    } as any

    const urlPrefix = ''
    // const urlPrefix = 'http://localhost:7001/'

    const $http = useHttp()

    const monaco = useMonacoEditor()

    const exercise = (() => {
        const url = urlPrefix + 'exercise';
        const {refs, onRef} = useRefs({expand: PlcExpand})
        const option = useTableOption({
            url: url,
            showRows: 10,
            sort: {
                field: 'createdAt',
                desc: true,
            },
            defaultNewRow: {
                type: 'ts',
                difficulty: '1_low',
            },
        })

        const previewContent = async (scope: TableRenderScope) => {
            refs.expand?.methods.toggle(scope.node)
        }

        const addContent = async (row: any) => {
            const newContent = await monaco.edit(row.content, {title: '题目内容'})
            await $http.put(url, {
                row: {
                    ...row,
                    content: newContent,
                }
            })
            option.pageMethods.load()
        }

        const render = () => (
            <PlTablePro option={option}>
                <PlcExpand field="content" noPadding ref={onRef.expand}>
                    {{
                        expand: ({row}) => (
                            <div>
                                {
                                    !row.content ?
                                        <div style={{padding: '16px'}}><PlButton label="添加题目内容" icon="el-icon-edit" onClick={() => exercise.addContent(row)}/></div> :
                                        <Markdown md={['```typescript', row.content, '```'].join('\n')}/>
                                }
                            </div>
                        )
                    }}
                </PlcExpand>
                <PlcInput title="标题" field="title" width={200}/>
                <PlcTextarea title="概述" field="comments" fit/>
                <PlcMonacoEditor title="题目内容" field="content" handlePreview={exercise.previewContent}/>
                <PlcOv title="难度" ov="exercise_difficulty" field="difficulty" width={120}>
                    {{
                        normal: ({row}) => (
                            <PlRate modelValue={diffToNum[row.difficulty].val} status={diffToNum[row.difficulty].status}/>
                        )
                    }}
                </PlcOv>
                <PlcOv title="类型" ov="exercise_type" field="type" width={80} align="center"/>
                <PlcTextarea title="相关资料" field="material" width={150}/>
                <PlcInput title="原文地址" field="origin" width={80}>
                    {{
                        normal: ({row}) => <a href={row.origin} target="_blank">{row.origin}</a>,
                    }}
                </PlcInput>
                <PlcDate title="创建时间" field="createdAt" editable={false} width={160}/>
            </PlTablePro>
        )

        return {
            option, previewContent, addContent, onRef, render,
        }
    })()

    const solution = (() => {
        const url = urlPrefix + 'exercise-solution'
        const {refs, onRef} = useRefs({expand: PlcExpand})
        const solution = useSolution()
        const addSolution = async () => {
            const parentRow = exercise.option.currentNode.value?.data
            if (!parentRow) {
                return $message.warn('请先选择练习题目！')
            }
            await solution.edit({
                parentId: parentRow.id
            }, async (editRow) => {
                await $http.post(url, {row: editRow})
            })
            await option.pageMethods.load()
        }
        const editSolution = async (row: any) => {
            await solution.edit(row, async (editRow) => {
                await $http.put(url, {row: editRow})
            })
            await option.pageMethods.load()
        }
        const option = useTableOption({
            url,
            enable: {insert: false, update: false, delete: true},
            showRows: 10,
            bodyRowHeight: 70,
            sort: {
                field: 'agree',
                desc: true,
            },
            buttons: [
                {
                    type: 'other',
                    seq: 1,
                    code: 'add-solution',
                    label: '提交答案',
                    position: 'out',
                    handler: addSolution,
                }
            ],
            defaultNewRow: {
                type: 'ts',
                difficulty: 'low',
            },
            parentOption: exercise.option,
            parentMap: {
                parentId: 'id',
            },
        })

        option.hooks.onDblClickCell.use((node) => {
            editSolution(node.editRow)
        })

        const previewContent = async (scope: TableRenderScope) => {
            refs.expand?.methods.toggle(scope.node)
        }

        const handler = {
            doAgree: async (row: any, {field, defaultValue, add}: { field: 'agree' | 'disagree', add?: boolean, defaultValue: number }, e: React.MouseEvent) => {
                if (!add) {
                    e.stopPropagation()
                }
                await $http.put(url, {
                    row: {
                        ...row,
                        [field]: Math.max(0, row[field] == null ? defaultValue : row[field] + (add ? 1 : -1))
                    }
                })
                await option.pageMethods.load()
            },
        }

        const render = () => <>
            <div className="pro-page-title pl-text-primary">
                参考答案
            </div>
            <PlTablePro option={option}>
                <PlcExpand field="content" noPadding ref={onRef.expand}>
                    {{
                        expand: ({row}) => (
                            <div style={{padding: '0 10px'}}>{!row.content ? '无内容！' : <Markdown md={row.content}/>}</div>
                        )
                    }}
                </PlcExpand>
                <PlcImage title="头像" field="avatar"/>
                <PlcInput title="提交人" field="author"/>
                <PlcMonacoEditor title="答案" field="content" handlePreview={previewContent}/>
                <Plc title="赞" field="agree" width={120} align="center">
                    {{
                        normal: ({row}) => (
                            <div className="exercise-agree-cell" data-active={String(row.agree > 0)} onClick={(e: React.MouseEvent) => handler.doAgree(row, {field: 'agree', defaultValue: 1, add: true}, e)}>
                                <i className="icon pp-font pp-thumb-up pl-background-success"/>
                                <span className="pl-background-success">{row.agree}</span>
                                <div>
                                    <PlIcon icon="el-icon-arrow-up" className="pl-background-success"/>
                                    <PlIcon icon="el-icon-arrow-down" className="pl-background-success" onClick={(e: React.MouseEvent) => handler.doAgree(row, {field: 'agree', defaultValue: 0, add: false}, e)}/>
                                </div>
                            </div>
                        )
                    }}
                </Plc>
                <Plc title="踩" field="disagree" width={100} align="center">
                    {{
                        normal: ({row}) => (
                            <div className="exercise-agree-cell" data-active={String(row.disagree > 0)} onClick={(e: React.MouseEvent) => handler.doAgree(row, {field: 'disagree', defaultValue: 1, add: true}, e)}>
                                <i className="icon pp-font pp-thumb-down pl-background-error"/>
                                <span className="pl-background-error">{row.disagree}</span>
                                <div>
                                    <PlIcon icon="el-icon-arrow-up" className="pl-background-error"/>
                                    <PlIcon icon="el-icon-arrow-down" className="pl-background-error" onClick={(e: React.MouseEvent) => handler.doAgree(row, {field: 'disagree', defaultValue: 0, add: false}, e)}/>
                                </div>
                            </div>
                        )
                    }}
                </Plc>
                <Plc title="提交时间" field="createdAt" width={170}/>
                <Plc title="更新时间" field="updatedAt" width={170}/>
            </PlTablePro>
        </>

        return {option, onRef, previewContent, render}
    })()

    return () => <>
        <div style={{backgroundColor: 'white'}}>
            {exercise.render()}
            {solution.render()}
        </div>
    </>
})
